/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
//import org.apache.shiro.ini.IniSecurityManagerFactory;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
//import org.apache.shiro.lang.util.Factory;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 简单的快速入门应用程序，展示如何使用Shiro的API。
 *
 * @since 0.9 RC2
 */
public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);


    /*  启动后输出：
            SLF4J: Class path contains multiple SLF4J bindings.
            SLF4J: Found binding in [jar:file:/E:/mavenRespository/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
            SLF4J: Found binding in [jar:file:/E:/mavenRespository/ch/qos/logback/logback-classic/1.2.10/logback-classic-1.2.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
            SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
            SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
            [main] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager - Enabling session validation scheduler...
            [main] INFO Quickstart - 检索到正确的值! [aValue]
            [main] INFO Quickstart - User [lonestarr] logged in successfully.
            [main] INFO Quickstart - May the Schwartz be with you!
            [main] INFO Quickstart - You may use a lightsaber ring.  Use it wisely.
            [main] INFO Quickstart - You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  Here are the keys - have fun!
     */

    public static void main(String[] args) {

        // 加载配置文件（用户配置的角色，以及角色分配的权限）创建工厂，工厂产出‘安全管理器’，拿到工厂实例，放置到安全工具中
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);


        // 获取当前正在执行的用户:
        Subject currentUser = SecurityUtils.getSubject();
        // 拿到当前会话
        Session session = currentUser.getSession();
        // 会话中放置属性key,value测试下是否能拿到
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("检索到正确的值! [" + value + "]");
        }



        // 用户、密码登录，身份验证
        if (!currentUser.isAuthenticated()) {
            // token 令牌，没有获取，随机
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);  // 设置记住我
            try {
                currentUser.login(token);  // 执行登录操作
            } catch (UnknownAccountException uae) {
                log.info("没有用户名为：" + token.getPrincipal() + "的用户!");
            } catch (IncorrectCredentialsException ice) {
                log.info("账户： " + token.getPrincipal() + " 密码错误!");
            } catch (LockedAccountException lae) {
                log.info("用户名" + token.getPrincipal() + "的帐户被锁定。请联系您的管理员解锁。");
            }catch (AuthenticationException ae) {
               //意想不到的条件?错误呢?
            }
        }

        // 打印出当前用户，登录成功
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

        // 验证是否有对应角色
        //测试角色:
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }

        // 验证是否有对应权限
        //测试类型化权限(非实例级)  粗粒度
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }
        //(非常强大的)实例级权限:  细粒度
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }

        //注销
        currentUser.logout();
        //结束
        System.exit(0);
    }
}
